import Vec3 from "./vec3";
import Method from "./method";

/**
 * elements:
 *      [
 *          minX,minY,minZ,         0
 *          maxX,maxY,maxZ          3
 *      ]
 */
export default class Aabb {
    constructor() {
        this.elements=new Float64Array(6);
        this.elements[0]=0;
        this.elements[1]=0;
        this.elements[2]=0;
        this.elements[3]=0;
        this.elements[4]=0;
        this.elements[5]=0;
    }
    get minX(){
        return this.elements[0];
    }
    set minX(n){
        this.elements[0]=n;
    }
    get minY(){
        return this.elements[1];
    }
    set minY(n){
        this.elements[1]=n;
    }
    get minZ(){
        return this.elements[2];
    }
    set minZ(n){
        this.elements[2]=n;
    }
    get maxX(){
        return this.elements[3];
    }
    set maxX(n){
        this.elements[3]=n;
    }
    get maxY(){
        return this.elements[4];
    }
    set maxY(n){
        this.elements[4]=n;
    }
    get maxZ(){
        return this.elements[5];
    }
    set maxZ(n){
        this.elements[5]=n;
    }

    init(min,max) {
        let _this=this.elements,i=min.elements,a=max.elements;
        _this[0] = i[0];_this[1] = i[1];_this[2] = i[2];
        _this[3] = a[0];_this[4] = a[1];_this[5] = a[2];
        return this;
    }
    getCenter() {
        let v = new Vec3();
        let _this=this.elements, es=v.elements;
        let cX = _this[0] + _this[3],cY = _this[1] + _this[4],cZ = _this[2] + _this[5];
        es[0] = cX*0.5;es[1] = cY*0.5;es[2] = cZ*0.5;
        return v;
    }
    combine(_other) {
        let _this=this.elements,other=_other.elements;
        _this[0] = _this[0] < other[0] ? _this[0] : other[0];
        _this[1] = _this[1] < other[1] ? _this[1] : other[1];
        _this[2] = _this[2] < other[2] ? _this[2] : other[2];
        _this[3] = _this[3] > other[3] ? _this[3] : other[3];
        _this[4] = _this[4] > other[4] ? _this[4] : other[4];
        _this[5] = _this[5] > other[5] ? _this[5] : other[5];
        return this;
    }
    combined(_other) {
        let _aabb = new Aabb();
        let aabb=_aabb.elements,other=_other.elements,_this=this.elements;
        aabb[0] = _this[0] < other[0] ? _this[0] : other[0];
        aabb[1] = _this[1] < other[1] ? _this[1] : other[1];
        aabb[2] = _this[2] < other[2] ? _this[2] : other[2];
        aabb[3] = _this[3] > other[3] ? _this[3] : other[3];
        aabb[4] = _this[4] > other[4] ? _this[4] : other[4];
        aabb[5] = _this[5] > other[5] ? _this[5] : other[5];
        return aabb;
    }
    overlap(_other) {
        let _this=this.elements,other=_other.elements;
        if(_this[0] < other[3] && _this[3] > other[0] && _this[1] < other[4] && _this[4] > other[1] && _this[2] < other[5]) {
            return _this[5] > other[2];
        } else {
            return false;
        }
    }
    copyFrom(_aabb) {
        let _this=this.elements,aabb=_aabb.elements;
        Method.copyElements(aabb,_this);
        return this;
    }
    clone() {
        let _aabb = new Aabb();
        let _this=this.elements,aabb=_aabb.elements;
        Method.copyElements(_this,aabb);
        return aabb;
    }
}